package com.ctshk.rpc.user.service.impl;
import com.ctshk.rpc.order.localfun.req.AppLocalFunOrderRefundDetailReq;
import com.ctshk.rpc.order.tour.req.client.ClientOrderCancelReq;

import cn.hutool.json.JSONUtil;
import com.ctshk.common.constant.ElasticSearchConstant;
import com.ctshk.common.constant.RedisConstants;
import com.ctshk.common.dto.Result;
import com.ctshk.common.enums.*;
import com.ctshk.common.enums.Currency;
import com.ctshk.common.enums.appUser.AppFilterOrderStatus;
import com.ctshk.common.enums.appUser.AppOrderStatus;
import com.ctshk.common.enums.appUser.OrderGmtCreateType;
import com.ctshk.common.exception.BusinessException;
import com.ctshk.common.model.PageResponse;
import com.ctshk.common.model.TokenUser;
import com.ctshk.common.utils.EntityUtil;
import com.ctshk.rpc.custom.service.ICustomizedTripScheduleInformationService;
import com.ctshk.rpc.hotel.dto.MyHotelOrderDTO;
import com.ctshk.rpc.hotel.service.IHotelOrderService;
import com.ctshk.rpc.order.air.dto.AirOrderListDTO;
import com.ctshk.rpc.order.air.req.AirOrderCancelReq;
import com.ctshk.rpc.order.air.req.orderDetail.AirOrderFlightData;
import com.ctshk.rpc.order.air.service.IAirOrderService;
import com.ctshk.rpc.order.air.service.app.IAirProductOrderService;
import com.ctshk.rpc.order.airexpress.dto.MyAirportExpressOrderDTO;
import com.ctshk.rpc.order.airexpress.req.AirportExpressOrderCancelReq;
import com.ctshk.rpc.order.airexpress.service.IAirportExpressOrderAppService;
import com.ctshk.rpc.order.airexpress.service.IAirportExpressOrderService;
import com.ctshk.rpc.order.bus.dto.MyBusOrderDTO;
import com.ctshk.rpc.order.bus.service.IBusOrderAppService;
import com.ctshk.rpc.order.bus.service.IBusOrderService;
import com.ctshk.rpc.order.custom.service.ICustomizedOrderService;
import com.ctshk.rpc.order.goods.dto.MyOrderDetailDTO;
import com.ctshk.rpc.order.goods.req.OrderCommodityRefundReq;
import com.ctshk.rpc.order.goods.service.IOrderService;
import com.ctshk.rpc.order.hotel.req.h5.HotelCancelOrderReq;
import com.ctshk.rpc.order.hotel.service.IHotelOrderH5Service;
import com.ctshk.rpc.order.localfun.dto.MyLocalFunOrderDTO;
import com.ctshk.rpc.order.localfun.req.LocalFun0rderCancelReq;
import com.ctshk.rpc.order.localfun.req.LocalFunOrderRefundDetailReq;
import com.ctshk.rpc.order.localfun.service.ILocalFunAppOrderService;
import com.ctshk.rpc.order.localfun.service.ILocalFunOrderService;
import com.ctshk.rpc.order.scenic.dto.MyScenicOrderDTO;
import com.ctshk.rpc.order.scenic.service.IScenicOrderService;
import com.ctshk.rpc.order.scenic.service.app.IScenicOrderAppService;
import com.ctshk.rpc.order.season.dto.MySeasonOrderDTO;
import com.ctshk.rpc.order.season.service.ISeasonOrderService;
import com.ctshk.rpc.order.ship.dto.MyShipOrderDTO;
import com.ctshk.rpc.order.ship.dto.MyShipOrderRouteDTO;
import com.ctshk.rpc.order.ship.service.IShipOrderService;
import com.ctshk.rpc.order.tour.code.TourPayStatusCode;
import com.ctshk.rpc.order.tour.dto.MyTripOrderDTO;
import com.ctshk.rpc.order.tour.service.ISeriesOrderService;
import com.ctshk.rpc.order.train.dto.TrainOrderDetailDTO;
import com.ctshk.rpc.order.train.req.TrainCancelOrderAppReq;
import com.ctshk.rpc.order.train.service.ITrainOrderAppService;
import com.ctshk.rpc.order.train.service.ITrainOrderService;
import com.ctshk.rpc.user.dto.*;
import com.ctshk.rpc.user.dto.es.*;
import com.ctshk.rpc.user.entity.es.*;
import com.ctshk.rpc.user.mapper.es.OrderEsMapper;
import com.ctshk.rpc.user.req.MobileQueryReq;
import com.ctshk.rpc.user.req.OrderCancelReq;
import com.ctshk.rpc.user.req.OrderPageReq;
import com.ctshk.rpc.user.service.IOrderEsService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.Criteria;
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
import org.springframework.data.elasticsearch.core.query.UpdateQuery;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.CollectionUtils;

import java.io.Serializable;
import java.math.BigDecimal;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.concurrent.CompletableFuture;

/**
 * <p>
 *
 * </p>
 *
 * @author 李新科
 * @date 2021/5/21 12:20
 */
@DubboService
@Slf4j
public class OrderEsServiceImpl implements IOrderEsService {

    @Autowired
    private OrderEsMapper orderEsMapper;

    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    @DubboReference(timeout = 60000)
    private ISeriesOrderService seriesOrderService;

    @DubboReference(timeout = 60000)
    private ISeasonOrderService seasonOrderService;

    @DubboReference(timeout = 60000)
    private IHotelOrderService hotelOrderService;

    @DubboReference(timeout = 60000)
    private IAirOrderService airOrderService;

    @DubboReference(timeout = 60000)
    private ITrainOrderService trainOrderService;

    @DubboReference(timeout = 60000)
    private IShipOrderService shipOrderService;

    @DubboReference(timeout = 60000)
    private IBusOrderService busOrderService;

    @DubboReference(timeout = 60000)
    private IAirportExpressOrderService airportExpressOrderService;

    @DubboReference(timeout = 60000)
    private IScenicOrderService scenicOrderService;

    @DubboReference(timeout = 60000)
    private ILocalFunOrderService localFunOrderService;

    @DubboReference(timeout = 60000)
    private IOrderService orderService;

    @DubboReference(timeout = 60000)
    private ICustomizedOrderService customizedOrderService;

    @DubboReference
    private ICustomizedTripScheduleInformationService customizedTripScheduleInformationService;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    // C端订单服务类
    @DubboReference
    private IHotelOrderH5Service hotelOrderH5Service;

    @DubboReference
    private IAirportExpressOrderAppService airportExpressOrderAppService;

    @DubboReference
    private IAirProductOrderService airProductOrderService;

    @DubboReference
    private ITrainOrderAppService trainOrderAppService;

    @DubboReference
    private IBusOrderAppService busOrderAppService;

    @DubboReference
    private IScenicOrderAppService scenicOrderAppService;

    @DubboReference
    private ILocalFunAppOrderService localFunAppOrderService;

    public static void main(String[] args) {
        LocalDateTime date = LocalDateTime.now();
        LocalDateTime firstday = date.with(TemporalAdjusters.firstDayOfMonth());
        LocalDateTime lastDay = date.with(TemporalAdjusters.lastDayOfMonth());
        System.out.println("firstday:" + firstday);
        System.out.println("lastDay:" + lastDay);
    }

    @Override
    public void saveOrderToEs(Serializable serializable, SystemBusinessType systemBusinessType) {
        CompletableFuture.runAsync(() -> {
            OrderEs orderEs = getOrderEs(serializable, systemBusinessType);
            orderEsMapper.save(orderEs);
        });
    }

    @Override
    public Result updateOrderToEs() {
        log.info("======开始拉取指定时间段的所有订单数据======");
        LocalDateTime now = LocalDateTime.now();
        // 上次查询的结束时间,从redis取

        //LocalDateTime recent = now.minusMinutes(5);
        // 查询每个单项最新的订单数据并更新到ES
        updateSeriesOrderToEs(now);
        //updateCustomOrderToEs(now);
        updateSeasonOrderToEs(now);
        updateHotelOrderToEs(now);
        updateAirOrderToEs(now);
        updateTrainOrderToEs(now);
        updateShipOrderToEs(now);
        updateBusOrderToEs(now);
        updateAirportExpressOrderToEs(now);
        updateScenicOrderToEs(now);
        updateLocalFunOrderToEs(now);
        updateOrderToEs(now);


        log.info("======更新到ES完毕======");
        return Result.success();
    }

    /**
     * 根据type查询该单项上次查询结束的时间
     *
     * @param type
     * @return
     */
    private LocalDateTime getRecentByType(int type) {
        String millisecondsStr = (String) redisTemplate.opsForValue().get(RedisConstants.USER_RECENT_TIME_KEY + type);
        LocalDateTime recent = null;
        Long milliseconds;
        if (millisecondsStr != null) {
            milliseconds = Long.valueOf(millisecondsStr);
            recent = LocalDateTime.ofInstant(Instant.ofEpochMilli(milliseconds), ZoneId.systemDefault());
        }

        return recent;
    }

    /**
     * 根据type更新该单项上次查询结束的时间
     *
     * @param type
     * @return
     */
    private void updateRecentByType(LocalDateTime now, int type) {
        long milliseconds = now.toInstant(ZoneOffset.ofHours(8)).toEpochMilli();
        redisTemplate.opsForValue().set(RedisConstants.USER_RECENT_TIME_KEY + type, String.valueOf(milliseconds));
    }


    private void updateSeriesOrderToEs(LocalDateTime now) {

        // 1，2旅行团
        CompletableFuture.runAsync(() -> {
            try {
                LocalDateTime recent = getRecentByType(SystemBusinessType.OUTBOUND_TRAVEL.getCode());
                Result<List<MyTripOrderDTO>> result = seriesOrderService.recentToNow(recent, now);
                List<OrderEs> list = new ArrayList<>();
                if (result.isSuccess()) {
                    List<MyTripOrderDTO> dataList = result.getData();
                    for (MyTripOrderDTO data : dataList) {
                        OrderEs orderEs = getOrderEs(data,SystemBusinessType.OUTBOUND_TRAVEL);
                        list.add(orderEs);
                    }
                    orderEsMapper.saveAll(list);
                    updateRecentByType(now, SystemBusinessType.OUTBOUND_TRAVEL.getCode());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    private OrderEs getOrderEs(Serializable serializable,SystemBusinessType systemBusinessType) {
        OrderEs orderEs = new OrderEs();
        Long id = null;
        String orderNumber = null;
        Long createId = null;
        Long shopId = null;
        BigDecimal orderAmount = null;
        Integer orderStatus = null;
        Integer paymentStatus = null;
        Integer scheduledStatus = null;
        Integer cancelStatus = null;
        LocalDateTime payExpireDateTime = null;
        String queryNumber = null;
        LocalDateTime gmtCreate = null;
        Long userId = null;
        Long productId = null;
        switch (systemBusinessType) {
            case FIXED_PACKAGE_TICKET:
                MySeasonOrderDTO fixedPackageTicketData = (MySeasonOrderDTO) serializable;
                id = fixedPackageTicketData.getId();
                orderNumber = fixedPackageTicketData.getOrderNumber();
                createId = fixedPackageTicketData.getCreateId();
                shopId = fixedPackageTicketData.getShopId();
                orderAmount = fixedPackageTicketData.getOrderAmount();
                paymentStatus = fixedPackageTicketData.getPaymentStatus();
                scheduledStatus = fixedPackageTicketData.getScheduledStatus();
                cancelStatus = fixedPackageTicketData.getCancelStatus();
                payExpireDateTime = fixedPackageTicketData.getPayExpireDate();
                gmtCreate = fixedPackageTicketData.getGmtCreate();
                userId = fixedPackageTicketData.getUserId();
                productId = fixedPackageTicketData.getProductId();

                orderEs.setSeasonOrder(new SeasonOrderEs()
                        .setProductName(fixedPackageTicketData.getProductName())
                        .setTicketNum(0)
                        .setDepartDate(fixedPackageTicketData.getDepartDate())
                        .setEndDate(LocalDate.now()));
                break;
            case HOTEL:
                MyHotelOrderDTO hotelData = (MyHotelOrderDTO) serializable;
                id = hotelData.getId();
                orderNumber = hotelData.getOrderNumber();
                createId = hotelData.getCreateId();
                shopId = hotelData.getShopId();
                orderAmount = hotelData.getOrderAmount();
                paymentStatus = hotelData.getPaymentStatus();
                scheduledStatus = hotelData.getScheduledStatus();
                cancelStatus = hotelData.getCancelStatus();
                payExpireDateTime = hotelData.getPayExpireDate();
                gmtCreate = hotelData.getGmtCreate();
                userId = hotelData.getUserId();
                productId = hotelData.getHotelId();

                orderEs.setHotelOrder(new HotelOrderEs().setHotelName(hotelData.getHotelName())
                        .setHotelEnName(hotelData.getHotelEnName())
                        .setCheckInDate(hotelData.getCheckInDate())
                        .setCheckOutDate(hotelData.getCheckOutDate())
                );
                break;
            case AIR_EXPRESS:
                MyAirportExpressOrderDTO airportExpressData = (MyAirportExpressOrderDTO) serializable;
                id = airportExpressData.getId();
                orderNumber = airportExpressData.getOrderNumber();
                createId = airportExpressData.getCreateId();
                shopId = airportExpressData.getShopId();
                orderAmount = airportExpressData.getOrderAmount();
                paymentStatus = airportExpressData.getPaymentStatus();
                scheduledStatus = airportExpressData.getScheduledStatus();
                cancelStatus = airportExpressData.getCancelStatus();
                payExpireDateTime = airportExpressData.getPayExpireDate();
                gmtCreate = airportExpressData.getGmtCreate();
                userId = airportExpressData.getUserId();
                queryNumber = airportExpressData.getInquiryNumber();
                productId = airportExpressData.getAirportExpressId();

                orderEs.setAirportExpressOrder(new AirportExpressOrderEs()
                        .setTicketTypeName(airportExpressData.getTicketTypeName())
                        .setTicketTypeEnName(airportExpressData.getTicketTypeEnName())
                        .setAdultTicketNumber(airportExpressData.getAdultTicketNumber())
                        .setChildrenTicketNumber(airportExpressData.getChildrenTicketNumber())
                        .setEffectiveTime(airportExpressData.getEffectiveTime())
                        .setTicketQrCodeUrl(airportExpressData.getTicketQrCodeUrl()));
                break;
            case COMMODITY:
                MyOrderDetailDTO commodityData = (MyOrderDetailDTO) serializable;
                id = commodityData.getId();
                orderNumber = commodityData.getOrderNumber();
                createId = commodityData.getCreateId();
                shopId = commodityData.getShopId();
                orderAmount = commodityData.getOrderAmount();
                orderStatus = commodityData.getOrderStatus();
                paymentStatus = commodityData.getPaymentStatus();
                scheduledStatus = commodityData.getScheduledStatus();
                cancelStatus = commodityData.getCancelStatus();
                payExpireDateTime = commodityData.getPayExpireDate();
                gmtCreate = commodityData.getGmtCreate();
                userId = commodityData.getUserId();
                queryNumber = commodityData.getSearchCode();

                orderEs.setCommodityOrder(new CommodityOrderEs()
                        .setCommodityOrderDetailList(EntityUtil.copyList(commodityData.getOrderCommodityPageListDetailDTOList(), CommodityOrderDetailEs.class)));
                break;
            case AIR_TICKET:
                AirOrderListDTO airData = (AirOrderListDTO) serializable;
                id = airData.getId();
                orderNumber = airData.getOrderNumber();
                createId = airData.getCreateId();
                shopId = airData.getShopId();
                orderAmount = airData.getOrderAmount();
                orderStatus = airData.getOrderStatus();
                paymentStatus = airData.getPaymentStatus();
                scheduledStatus = airData.getScheduledStatus();
                cancelStatus = airData.getCancelStatus();
                payExpireDateTime = airData.getPayExpireDate();
                gmtCreate = airData.getGmtCreate();
                userId = airData.getUserId();

                List<AirOrderFlightData> airOrderFlightDataList = airData.getAirOrderFlightDataList();
                if (!CollectionUtils.isEmpty(airOrderFlightDataList)) {
                    List<AirOrderTripEs> airOrderTripList = new ArrayList<>();
                    for (AirOrderFlightData airOrderFlightData : airOrderFlightDataList) {
                        AirOrderTripEs airOrderTripEs = new AirOrderTripEs();
                        airOrderTripEs.setCompanyName(airOrderFlightData.getCompanyName());
                        airOrderTripEs.setTripRank(airOrderFlightData.getTripRank());
                        airOrderTripEs.setFlightNumber(airOrderFlightData.getFlightNumber());
                        LocalDate date = airOrderFlightData.getDate();
                        if (date != null) {
                            if (airOrderFlightData.getDepTime() != null) {
                                airOrderTripEs.setDepDateTime(airOrderFlightData.getDepTime().atDate(date));
                            }

                            if (airOrderFlightData.getArrTime() != null) {
                                airOrderTripEs.setDepDateTime(airOrderFlightData.getArrTime().atDate(date));
                            }
                        }
                        airOrderTripEs.setDepCityName(airOrderFlightData.getDepCityName());
                        airOrderTripEs.setArrCityName(airOrderFlightData.getArrCityName());
                        airOrderTripEs.setDepAirportName(airOrderFlightData.getDepAirportName());
                        airOrderTripEs.setArrAirportName(airOrderFlightData.getArrAirportName());

                        airOrderTripEs.setTimeConsuming(airOrderFlightData.getTimeConsuming());
                        airOrderTripList.add(airOrderTripEs);
                    }
                    orderEs.setAirOrder(new AirOrderEs()
                            .setAirOrderTripList(airOrderTripList)
                            .setTripType(airData.getTripType()));
                }
                break;
            case TRAIN_TICKET:
                TrainOrderDetailDTO trainData = (TrainOrderDetailDTO) serializable;
                id = trainData.getId();
                orderNumber = trainData.getOrderNumber();
                createId = trainData.getCreateId();
                shopId = trainData.getShopId();
                orderAmount = trainData.getOrderAmount();
                orderStatus = trainData.getOrderStatus();
                paymentStatus = trainData.getPaymentStatus();
                scheduledStatus = trainData.getScheduledStatus();
                cancelStatus = trainData.getCancelStatus();
                payExpireDateTime = trainData.getPayExpireDate();
                gmtCreate = trainData.getGmtCreate();
                userId = trainData.getUserId();

                // TODO 单项独有字段填充 车厢号和座位号缺失
                orderEs.setTrainOrder(new TrainOrderEs()
                        .setTypeName(trainData.getTrainNumberName())
                        //.setSeatNum("15")
                        //.setCarNum("03")
                        .setTypeName(trainData.getTrainNumberName())
                        .setDepartureDateTime(trainData.getDepartureTime())
                        .setDepartureCityName(trainData.getDepartureCityName())
                        .setArriveCityName(trainData.getArriveCityName())
                        .setBoardingStationName(trainData.getBoardingStationName())
                        .setAlightingStationName(trainData.getAlightingStationName())
                );
                break;
            case BUS_TICKET:
                MyBusOrderDTO busData = (MyBusOrderDTO) serializable;
                id = busData.getId();
                orderNumber = busData.getOrderNumber();
                createId = busData.getCreateId();
                shopId = busData.getShopId();
                orderAmount = busData.getOrderAmount();
                paymentStatus = busData.getPaymentStatus();
                scheduledStatus = busData.getScheduledStatus();
                cancelStatus = busData.getCancelStatus();
                payExpireDateTime = busData.getPayExpireDate();
                gmtCreate = busData.getGmtCreate();
                userId = busData.getUserId();
                //  单项独有字段填充

                orderEs.setBusOrder(new BusOrderEs()
                        .setEffectiveTime(busData.getEffectiveTime())
                        .setEstimatedTime(busData.getEstimatedTime())
                        .setDepartureCityName(busData.getDepartureCityName())
                        .setArriveCityName(busData.getArriveCityName())
                        .setBoardingStationName(busData.getBoardingStationName())
                        .setAlightingStationName(busData.getAlightingStationName())
                );
                break;
            case SHIP_TICKET:
                MyShipOrderDTO shipData = (MyShipOrderDTO) serializable;
                id = shipData.getId();
                orderNumber = shipData.getOrderNumber();
                createId = shipData.getCreateId();
                shopId = shipData.getShopId();
                orderAmount = shipData.getOrderAmount();
                paymentStatus = shipData.getPaymentStatus();
                scheduledStatus = shipData.getScheduledStatus();
                cancelStatus = shipData.getCancelStatus();
                payExpireDateTime = shipData.getPayExpireDate();
                gmtCreate = shipData.getGmtCreate();
                userId = shipData.getUserId();
                List<MyShipOrderRouteDTO> shipOrderRouteList = shipData.getShipOrderRouteList();
                orderEs.setShipOrder(new ShipOrderEs()
                        .setTripType(shipData.getTripType())
                        .setShipOrderTripList(EntityUtil.copyList(shipOrderRouteList, ShipOrderTripEs.class)));

                break;
            case ATTRACTION_TICKET:
                MyScenicOrderDTO scenicData = (MyScenicOrderDTO) serializable;
                id = scenicData.getId();
                orderNumber = scenicData.getOrderNumber();
                createId = scenicData.getCreateId();
                shopId = scenicData.getShopId();
                orderAmount = scenicData.getOrderAmount();
                paymentStatus = scenicData.getPaymentStatus();
                scheduledStatus = scenicData.getScheduledStatus();
                cancelStatus = scenicData.getCancelStatus();
                payExpireDateTime = scenicData.getPayExpireDate();
                gmtCreate = scenicData.getGmtCreate();
                userId = scenicData.getUserId();
                queryNumber = scenicData.getQueryNumber();
                productId = scenicData.getProductId();
                orderEs.setScenicOrder(new ScenicOrderEs()
                        .setProductName(scenicData.getProductName())
                        .setTicketNum(scenicData.getProductTicketNumber())
                        .setVaildDayBegin(scenicData.getVaildDayBegin())
                        .setVaildDayEnd(scenicData.getVaildDayEnd())
                );
                break;
            case LOCAL_FUN:
                MyLocalFunOrderDTO localFunData = (MyLocalFunOrderDTO) serializable;
                id = localFunData.getId();
                orderNumber = localFunData.getOrderNumber();
                createId = localFunData.getCreateId();
                shopId = localFunData.getShopId();
                orderAmount = localFunData.getOrderAmount();
                paymentStatus = localFunData.getPaymentStatus();
                scheduledStatus = localFunData.getScheduledStatus();
                cancelStatus = localFunData.getCancelStatus();
                payExpireDateTime = localFunData.getPayExpireDate();
                gmtCreate = localFunData.getGmtCreate();
                userId = localFunData.getUserId();
                queryNumber = localFunData.getQueryNumber();
                productId = localFunData.getProductId();
                orderEs.setLocalFunOrder(new LocalFunOrderEs()
                        .setProductName(localFunData.getProductName())
                        .setTicketNum(localFunData.getTicketNum())
                        .setUseDate(localFunData.getUseDate()));
                break;
            case OUTBOUND_TRAVEL:
                MyTripOrderDTO outboundTravelData = (MyTripOrderDTO) serializable;
                id = outboundTravelData.getId();
                orderNumber = outboundTravelData.getOrderNumber();
                createId = outboundTravelData.getCreateId();
                shopId = outboundTravelData.getShopId();
                orderAmount = outboundTravelData.getOrderAmount();
                orderStatus = outboundTravelData.getOrderStatus();
                paymentStatus = outboundTravelData.getIsPay();
                scheduledStatus = outboundTravelData.getScheduledStatus();
                cancelStatus = outboundTravelData.getCancelStatus();
                payExpireDateTime = outboundTravelData.getPayExpireDateTime();
                queryNumber = outboundTravelData.getQueryNumber();
                gmtCreate = outboundTravelData.getGmtCreate();
                userId = outboundTravelData.getUserId();
                productId = outboundTravelData.getTripId();
                orderEs.setTripOrder(new TripOrderEs().setTripTitle(outboundTravelData.getTripTitle())
                        .setDepartDate(outboundTravelData.getDepartDate())
                        .setTouristInfo(outboundTravelData.getTouristInfo()));
                break;
            case INBOUND_TRAVEL:
                MyTripOrderDTO inboundTravelData = (MyTripOrderDTO) serializable;
                id = inboundTravelData.getId();
                orderNumber = inboundTravelData.getOrderNumber();
                createId = inboundTravelData.getCreateId();
                shopId = inboundTravelData.getShopId();
                orderAmount = inboundTravelData.getOrderAmount();
                orderStatus = inboundTravelData.getOrderStatus();
                paymentStatus = inboundTravelData.getIsPay();
                scheduledStatus = inboundTravelData.getScheduledStatus();
                cancelStatus = inboundTravelData.getCancelStatus();
                payExpireDateTime = inboundTravelData.getPayExpireDateTime();
                queryNumber = inboundTravelData.getQueryNumber();
                gmtCreate = inboundTravelData.getGmtCreate();
                userId = inboundTravelData.getUserId();
                productId = inboundTravelData.getTripId();
                orderEs.setTripOrder(new TripOrderEs().setTripTitle(inboundTravelData.getTripTitle())
                        .setDepartDate(inboundTravelData.getDepartDate())
                        .setTouristInfo(inboundTravelData.getTouristInfo()));
                break;
            default:
                Result.failed(SystemError.SYS_437);
        }

        orderEs.setType(systemBusinessType.getCode());
        orderEs.setTypeName(systemBusinessType.getValue());
        orderEs.setId(id);
        orderEs.setOrderNumber(orderNumber);
        orderEs.setCreateId(createId);
        orderEs.setCurrency(Currency.HKD.getCurrency());
        orderEs.setCurrencyId(Currency.HKD.getCode());
        orderEs.setOrderAmount(orderAmount);
        orderEs.setOrderStatus(orderStatus);
        orderEs.setPaymentStatus(paymentStatus);
        orderEs.setScheduledStatus(scheduledStatus);
        orderEs.setCancelStatus(cancelStatus);
        orderEs.setPayExpireDateTime(payExpireDateTime);
        orderEs.setQueryNumber(queryNumber);
        orderEs.setGmtCreate(gmtCreate);
        orderEs.setUserId(userId);
        orderEs.setShopId(shopId);
        orderEs.setProductId(productId);
        setFrontOrderStatusAndFilterOrderStatus(orderEs);

        return orderEs;
    }


    private void updateCustomOrderToEs(LocalDateTime now) {

        // 3,4定制游
        CompletableFuture.runAsync(() -> {
            try {
                /*LocalDateTime recent = getRecentByType(SystemBusinessType.OUTBOUND_CUSTOMIZATION.getCode());
                Result<List<MyCustomizedOrderDTO>> result = customizedOrderService.recentToNow(recent,now);
                List<OrderEs> list = new ArrayList<>();
                if(result.isSuccess()) {
                    List<MyCustomizedOrderDTO> dataList = result.getData();
                    for (MyCustomizedOrderDTO data : dataList) {
                        OrderEs orderEs = new OrderEs();
                        orderEs.setType(SystemBusinessType.OUTBOUND_CUSTOMIZATION.getCode());
                        orderEs.setTypeName(SystemBusinessType.OUTBOUND_CUSTOMIZATION.getValue());
                        orderEs.setId(data.getId());
                        orderEs.setOrderNumber(data.getOrderNumber());
                        orderEs.setCreateId(data.getCreateId());
                        orderEs.setCurrency(Currency.HKD.getCurrency());
                        orderEs.setCurrencyId(Currency.HKD.getCode());
                        orderEs.setOrderAmount(data.getOrderAmount());
                        orderEs.setOrderStatus(data.getOrderStatus());
                        orderEs.setScheduledStatus(data.getScheduledStatus());
                        orderEs.setPayExpireDateTime(data.getPayExpireDateTime());
                        orderEs.setPaymentStatus(data.getIsPay());
                        orderEs.setQueryNumber(data.getQueryNumber());
                        orderEs.setGmtCreate(data.getGmtCreate());
                        orderEs.setTripOrder(new TripOrderEs().setTripTitle(data.getTripTitle())
                                .setDepartDate(data.getDepartDate())
                                .setTouristInfo(data.getTouristInfo()));

                        list.add(orderEs);
                    }
                    //elasticsearchRestTemplate.save(list);
                    orderEsMapper.saveAll(list);
                    updateRecentByType(now, SystemBusinessType.OUTBOUND_TRAVEL.getCode());
                }*/
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    private void updateSeasonOrderToEs(LocalDateTime now) {
        // 6固定套票
        CompletableFuture.runAsync(() -> {
            try {
                LocalDateTime recent = getRecentByType(SystemBusinessType.FIXED_PACKAGE_TICKET.getCode());
                Result<List<MySeasonOrderDTO>> result = seasonOrderService.recentToNow(recent, now);
                List<OrderEs> list = new ArrayList<>();
                if (result.isSuccess()) {
                    List<MySeasonOrderDTO> dataList = result.getData();
                    for (MySeasonOrderDTO data : dataList) {
                        OrderEs orderEs = getOrderEs(data, SystemBusinessType.FIXED_PACKAGE_TICKET);
                        list.add(orderEs);
                    }
                    orderEsMapper.saveAll(list);
                    updateRecentByType(now, SystemBusinessType.FIXED_PACKAGE_TICKET.getCode());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    private void updateHotelOrderToEs(LocalDateTime now) {
        CompletableFuture.runAsync(() -> {
            try {
                LocalDateTime recent = getRecentByType(SystemBusinessType.HOTEL.getCode());
                // 8.酒店
                Result<List<MyHotelOrderDTO>> result = hotelOrderService.recentToNow(recent, now);
                List<OrderEs> list = new ArrayList<>();
                if (result.isSuccess()) {
                    List<MyHotelOrderDTO> dataList = result.getData();
                    for (MyHotelOrderDTO data : dataList) {
                        OrderEs orderEs = getOrderEs(data, SystemBusinessType.HOTEL);
                        list.add(orderEs);
                    }
                    orderEsMapper.saveAll(list);
                    updateRecentByType(now, SystemBusinessType.HOTEL.getCode());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    private void updateAirOrderToEs(LocalDateTime now) {
        CompletableFuture.runAsync(() -> {
            try {
                LocalDateTime recent = getRecentByType(SystemBusinessType.AIR_TICKET.getCode());
                // 9.机票
                Result<List<AirOrderListDTO>> result = airOrderService.recentToNow(recent, now);
                List<OrderEs> list = new ArrayList<>();
                if (result.isSuccess()) {
                    List<AirOrderListDTO> dataList = result.getData();
                    for (AirOrderListDTO data : dataList) {
                        OrderEs orderEs = getOrderEs(data, SystemBusinessType.AIR_TICKET);
                        list.add(orderEs);
                    }
                    orderEsMapper.saveAll(list);
                    updateRecentByType(now, SystemBusinessType.AIR_TICKET.getCode());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    private void updateTrainOrderToEs(LocalDateTime now) {
        CompletableFuture.runAsync(() -> {
            try {
                LocalDateTime recent = getRecentByType(SystemBusinessType.TRAIN_TICKET.getCode());
                // 10.火车票
                Result<List<TrainOrderDetailDTO>> result = trainOrderService.recentToNow(recent, now);
                List<OrderEs> list = new ArrayList<>();
                if (result.isSuccess()) {
                    List<TrainOrderDetailDTO> dataList = result.getData();
                    for (TrainOrderDetailDTO data : dataList) {
                        OrderEs orderEs = getOrderEs(data, SystemBusinessType.TRAIN_TICKET);
                        list.add(orderEs);
                    }
                    orderEsMapper.saveAll(list);
                    updateRecentByType(now, SystemBusinessType.TRAIN_TICKET.getCode());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    private void updateShipOrderToEs(LocalDateTime now) {
        CompletableFuture.runAsync(() -> {
            try {
                LocalDateTime recent = getRecentByType(SystemBusinessType.SHIP_TICKET.getCode());
                // 11船票
                Result<List<MyShipOrderDTO>> result = shipOrderService.recentToNow(recent, now);
                List<OrderEs> list = new ArrayList<>();
                if (result.isSuccess()) {
                    List<MyShipOrderDTO> dataList = result.getData();
                    for (MyShipOrderDTO data : dataList) {
                        OrderEs orderEs = getOrderEs(data, SystemBusinessType.SHIP_TICKET);
                        list.add(orderEs);
                    }
                    orderEsMapper.saveAll(list);
                    updateRecentByType(now, SystemBusinessType.SHIP_TICKET.getCode());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    private void updateBusOrderToEs(LocalDateTime now) {
        CompletableFuture.runAsync(() -> {
            try {
                LocalDateTime recent = getRecentByType(SystemBusinessType.BUS_TICKET.getCode());
                // 12,巴士票
                Result<List<MyBusOrderDTO>> result = busOrderService.recentToNow(recent, now);
                List<OrderEs> list = new ArrayList<>();
                if (result.isSuccess()) {
                    List<MyBusOrderDTO> dataList = result.getData();
                    for (MyBusOrderDTO data : dataList) {
                        OrderEs orderEs = getOrderEs(data, SystemBusinessType.BUS_TICKET);
                        list.add(orderEs);
                    }
                    orderEsMapper.saveAll(list);
                    updateRecentByType(now, SystemBusinessType.BUS_TICKET.getCode());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    private void updateAirportExpressOrderToEs(LocalDateTime now) {
        CompletableFuture.runAsync(() -> {
            try {
                LocalDateTime recent = getRecentByType(SystemBusinessType.AIR_EXPRESS.getCode());
                // 13.机场快线
                Result<List<MyAirportExpressOrderDTO>> result = airportExpressOrderService.recentToNow(recent, now);
                List<OrderEs> list = new ArrayList<>();
                if (result.isSuccess()) {
                    List<MyAirportExpressOrderDTO> dataList = result.getData();
                    for (MyAirportExpressOrderDTO data : dataList) {
                        OrderEs orderEs = getOrderEs(data, SystemBusinessType.AIR_EXPRESS);
                        list.add(orderEs);
                    }
                    orderEsMapper.saveAll(list);
                    updateRecentByType(now, SystemBusinessType.AIR_EXPRESS.getCode());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    private void updateScenicOrderToEs(LocalDateTime now) {
        CompletableFuture.runAsync(() -> {
            try {
                LocalDateTime recent = getRecentByType(SystemBusinessType.ATTRACTION_TICKET.getCode());
                // 14景点门票
                Result<List<MyScenicOrderDTO>> result = scenicOrderService.recentToNow(recent, now);
                List<OrderEs> list = new ArrayList<>();
                if (result.isSuccess()) {
                    List<MyScenicOrderDTO> dataList = result.getData();
                    for (MyScenicOrderDTO data : dataList) {
                        OrderEs orderEs = getOrderEs(data, SystemBusinessType.ATTRACTION_TICKET);
                        list.add(orderEs);
                    }
                    orderEsMapper.saveAll(list);
                    updateRecentByType(now, SystemBusinessType.ATTRACTION_TICKET.getCode());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    private void updateLocalFunOrderToEs(LocalDateTime now) {
        CompletableFuture.runAsync(() -> {
            try {
                LocalDateTime recent = getRecentByType(SystemBusinessType.LOCAL_FUN.getCode());
                // 15当地玩乐
                Result<List<MyLocalFunOrderDTO>> result = localFunOrderService.recentToNow(recent, now);
                List<OrderEs> list = new ArrayList<>();
                if (result.isSuccess()) {
                    List<MyLocalFunOrderDTO> dataList = result.getData();
                    for (MyLocalFunOrderDTO data : dataList) {
                        OrderEs orderEs = getOrderEs(data, SystemBusinessType.LOCAL_FUN);
                        list.add(orderEs);
                    }
                    orderEsMapper.saveAll(list);
                    updateRecentByType(now, SystemBusinessType.LOCAL_FUN.getCode());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    private void updateOrderToEs(LocalDateTime now) {
        CompletableFuture.runAsync(() -> {
            try {
                LocalDateTime recent = getRecentByType(SystemBusinessType.COMMODITY.getCode());
                // 18商品
                Result<List<MyOrderDetailDTO>> result = orderService.recentToNow(recent, now);
                List<OrderEs> list = new ArrayList<>();
                if (result.isSuccess()) {
                    List<MyOrderDetailDTO> dataList = result.getData();
                    for (MyOrderDetailDTO data : dataList) {
                        if (data.getId() != null) {
                            OrderEs orderEs = getOrderEs(data, SystemBusinessType.COMMODITY);
                            list.add(orderEs);
                        }

                    }
                    orderEsMapper.saveAll(list);
                    updateRecentByType(now, SystemBusinessType.COMMODITY.getCode());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }


    @Override
    public Result<PageResponse<OrderEsDTO>> queryPage(OrderPageReq req) throws Exception {
        Pageable pageable = PageRequest.of(req.getPageNo() - 1, req.getPageSize());
        Sort sort = Sort.by(Sort.Direction.DESC, "gmtCreate");
        // Page<OrderEs> page = orderEsMapper.findByCreateId(req.getCreateId(), pageable);
        //Page<OrderEs> page = null;
        List<OrderEsDTO> orderEsDTOList = new ArrayList<>();
        long totalPages = 0;
        int pageNo = req.getPageNo();
        int pageSize = req.getPageSize();
        try {
            Criteria criteria = new Criteria();
            if(req.getCreateId() != null) {
                // 根据CreateId筛选B端销售人
                criteria.and(new Criteria("createId").is(req.getCreateId()));
            }
            if(req.getUserId() != null) {
                // 根据userId筛选C端下单人
                criteria.and(new Criteria("userId").is(req.getUserId()));
            }
            if (req.getShopId() != null) {
                criteria.and(new Criteria("shopId").is(req.getShopId()));
            }
            if (!CollectionUtils.isEmpty(req.getTypeList())) {
                criteria.and(new Criteria("type").in(req.getTypeList()));
            }
            if (req.getOrderNumber() != null) {
                criteria.and(new Criteria("orderNumber").is(req.getOrderNumber()));
            }
            if (req.getFilterOrderStatus() != null) {
                criteria.and(new Criteria("filterOrderStatus").is(req.getFilterOrderStatus()));
            }
            if (IsDeletedCode.NO.getCode().equals(req.getIsDeleted())) {
                criteria.and(new Criteria("isDeleted").notIn(IsDeletedCode.YES.getCode()));
            }
            LocalDateTime now = LocalDateTime.now();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            if(req.getYearOfMonth() != null) {
                LocalDate yearOfMonth = req.getYearOfMonth();
                LocalDateTime firstday = LocalDateTime.of(yearOfMonth, LocalTime.MIN);
                LocalDateTime nextMonthFirstday = firstday.plusMonths(1);
                criteria.and(new Criteria("gmtCreate")
                        .greaterThanEqual(firstday.format(formatter))
                        .lessThan(nextMonthFirstday.format(formatter)));
            }

            if (req.getGmtCreateType() != null) {
                Integer gmtCreateType = req.getGmtCreateType();
                if (OrderGmtCreateType.NEAR.getCode() == gmtCreateType) {
                    //sort.and(Sort.by(Sort.Direction.DESC, "gmtCreate"));
                } else if (OrderGmtCreateType.FAR.getCode() == gmtCreateType) {
                    sort = Sort.by(Sort.Direction.ASC, "gmtCreate");
                } else if (OrderGmtCreateType.THREE_MONTHS.getCode() == gmtCreateType) {
                    LocalDateTime localDateTime = now.minusMonths(3);
                    criteria.and(new Criteria("gmtCreate")
                            .between(localDateTime.format(formatter), now.format(formatter)));
                } else if (OrderGmtCreateType.HALF_YEAR.getCode() == gmtCreateType) {
                    LocalDateTime localDateTime = now.minusMonths(6);
                    criteria.and(new Criteria("gmtCreate")
                            .between(localDateTime.format(formatter), now.format(formatter)));
                } else if (OrderGmtCreateType.YEAR.getCode() == gmtCreateType) {
                    LocalDateTime localDateTime = now.minusYears(1);
                    criteria.and(new Criteria("gmtCreate")
                            .between(localDateTime.format(formatter), now.format(formatter)));
                } else if (OrderGmtCreateType.TODAY.getCode() == gmtCreateType) {
                    LocalDateTime localDateTime = LocalDateTime.of(now.toLocalDate(), LocalTime.MIN);
                    criteria.and(new Criteria("gmtCreate")
                            .between(localDateTime.format(formatter), now.format(formatter)));
                } else if (OrderGmtCreateType.YESTERDAY.getCode() == gmtCreateType) {
                    LocalDateTime localDateTime = LocalDateTime.of(now.minusDays(1).toLocalDate(), LocalTime.MIN);
                    LocalDateTime localDateTime2 = LocalDateTime.of(now.minusDays(1).toLocalDate(), LocalTime.MAX);
                    criteria.and(new Criteria("gmtCreate")
                            .between(localDateTime.format(formatter), localDateTime2.format(formatter)));
                } else if (OrderGmtCreateType.WEEK.getCode() == gmtCreateType) {
                    LocalDateTime localDateTime = now.minusDays(7);
                    criteria.and(new Criteria("gmtCreate")
                            .between(localDateTime.format(formatter), now.format(formatter)));
                } else if (OrderGmtCreateType.MONTH.getCode() == gmtCreateType) {
                    LocalDateTime localDateTime = now.minusMonths(1);
                    criteria.and(new Criteria("gmtCreate")
                            .between(localDateTime.format(formatter), now.format(formatter)));
                }
            }

            CriteriaQuery criteriaQuery = new CriteriaQuery(criteria).setPageable(pageable)
                    .addSort(sort);
            SearchHits<OrderEs> search = elasticsearchRestTemplate.search(criteriaQuery, OrderEs.class, IndexCoordinates.of(ElasticSearchConstant.ORDER_INDEX));
            List<SearchHit<OrderEs>> searchHits = search.getSearchHits();
            totalPages = search.getTotalHits();
            for (SearchHit<OrderEs> searchHit : searchHits) {
                OrderEs orderEs = searchHit.getContent();
                OrderEsDTO orderEsDTO = EntityUtil.copy(orderEs, OrderEsDTO.class);
                setOrder(orderEsDTO, orderEs);
                orderEsDTOList.add(orderEsDTO);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        //List<OrderEs> orderEsList = page.getContent();
        //List<OrderEsDTO> orderEsDTOList = copyList(orderEsList);
        PageResponse<OrderEsDTO> result = new PageResponse<>(orderEsDTOList, req.getPageNo() - 1 == 0,
                pageNo * pageSize >= totalPages, totalPages, req.getPageNo(), req.getPageSize());
        return Result.success(result);
    }

    /**
     * 根据业务类型集合构建订单实际状态的条件
     *
     * @param criteria
     * @param typeList
     * @param orderStatus 订单筛选字段,1待付款，2已付款，3已取消，4已完成，5售后中
     */
    private void buildOrderStatusCriteria(Criteria criteria, List<Integer> typeList, Integer orderStatus) {
        for (Integer type : typeList) {
            buildOrderStatusCriteria(criteria, type, orderStatus);
        }
    }

    /**
     * 根据业务类型集合构建订单实际状态的条件
     *
     * @param criteria
     * @param type
     * @param orderStatus 订单筛选字段,1待付款，2已付款，3已取消，4已完成，5售后中
     */
    private void buildOrderStatusCriteria(Criteria criteria, Integer type, Integer orderStatus) {
        if (SystemBusinessType.OUTBOUND_TRAVEL.getCode() == type) {
            Criteria criteriaSub = new Criteria("type").is(SystemBusinessType.OUTBOUND_TRAVEL.getCode());
            if (AppFilterOrderStatus.UN_PAYMENT.getCode() == orderStatus) {
                criteriaSub.and(new Criteria("paymentStatus").is(TourPayStatusCode.UN_PAYMENT.getCode().intValue()));
            } else if (AppFilterOrderStatus.PAYMENT.getCode() == orderStatus) {
                criteriaSub.and(new Criteria("paymentStatus").is(TourPayStatusCode.ALREADY_PAYMENT.getCode().intValue()));
            } else if (AppFilterOrderStatus.CANCEL.getCode() == orderStatus) {
                criteriaSub.and(new Criteria("orderStatus").in(2, 3));
            } else if (AppFilterOrderStatus.COMPLETE.getCode() == orderStatus) {
                criteriaSub.and(new Criteria("orderStatus").is(1));
            } else if (AppFilterOrderStatus.AFTER_SALE.getCode() == orderStatus) {
                criteriaSub.and(new Criteria("cancelStatus").in(OrderCancelStatus.UNDER_APPROVAL.getCode()
                        , OrderCancelStatus.APPROVAL_SUCCESS.getCode()
                        , OrderCancelStatus.APPROVAL_FAIL.getCode()
                        , OrderCancelStatus.ALREADY_REFUND.getCode()));
            }
            criteria.and(criteriaSub);
        }  else if (SystemBusinessType.COMMODITY.getCode() == type) {
            Criteria criteriaSub = new Criteria("type").is(SystemBusinessType.COMMODITY.getCode());
            if (AppFilterOrderStatus.UN_PAYMENT.getCode() == orderStatus) {
                criteriaSub.and(new Criteria("orderStatus").is(1));
                criteriaSub.and(new Criteria("paymentStatus").is(1));
                criteriaSub.and(new Criteria("scheduledStatus").is(0));
                criteriaSub.and(new Criteria("cancelStatus").is(0));
            } else if (AppFilterOrderStatus.PAYMENT.getCode() == orderStatus) {
                criteriaSub.and(new Criteria("orderStatus").is(2));
                criteriaSub.and(new Criteria("paymentStatus").is(2));
                criteriaSub.and(new Criteria("scheduledStatus").is(1));
                criteriaSub.and(new Criteria("cancelStatus").is(0));
            } else if (AppFilterOrderStatus.CANCEL.getCode() == orderStatus) {
                criteriaSub.and(new Criteria("orderStatus").is(5));
                criteriaSub.and(new Criteria("paymentStatus").is(2));
                criteriaSub.and(new Criteria("scheduledStatus").is(1));
                criteriaSub.and(new Criteria("cancelStatus").is(2));
            } else if (AppFilterOrderStatus.COMPLETE.getCode() == orderStatus) {
                criteriaSub.and(new Criteria("orderStatus").is(4));
            } else if (AppFilterOrderStatus.AFTER_SALE.getCode() == orderStatus) {
                criteriaSub.and(new Criteria("orderStatus").is(4));
                criteriaSub.and(new Criteria("paymentStatus").is(2));
                criteriaSub.and(new Criteria("scheduledStatus").is(1));
                criteriaSub.and(new Criteria("cancelStatus").in(1,2,3));
            }
            criteria.and(criteriaSub);
        } else {
            buildOrderStatusCriteriaCommon(criteria, orderStatus, type);
        }
    }

    private void buildOrderStatusCriteriaCommon(Criteria criteria, Integer orderStatus, Integer type) {
        Criteria criteriaSub = new Criteria("type").is(type);
        if (AppFilterOrderStatus.UN_PAYMENT.getCode() == orderStatus) {
            criteriaSub.and(new Criteria("paymentStatus").is(OrderPaymentStatus.UN_PAYMENT.getCode().intValue()));
        } else if (AppFilterOrderStatus.PAYMENT.getCode() == orderStatus) {
            criteriaSub.and(new Criteria("paymentStatus").is(OrderPaymentStatus.ALREADY_PAYMENT.getCode().intValue()));
        } else if (AppFilterOrderStatus.CANCEL.getCode() == orderStatus) {
            criteriaSub.and(new Criteria("paymentStatus").is(OrderPaymentStatus.ALREADY_CANCEL.getCode().intValue()));
        } else if (AppFilterOrderStatus.COMPLETE.getCode() == orderStatus) {
            criteriaSub.and(new Criteria("scheduledStatus").is(OrderScheduledStatus.RESERVE_SUCCESS.getCode()));
        } else if (AppFilterOrderStatus.AFTER_SALE.getCode() == orderStatus) {
            criteriaSub.and(new Criteria("cancelStatus").in(OrderCancelStatus.UNDER_APPROVAL.getCode()
                    , OrderCancelStatus.APPROVAL_SUCCESS.getCode()
                    , OrderCancelStatus.APPROVAL_FAIL.getCode()
                    , OrderCancelStatus.ALREADY_REFUND.getCode()));
        }
        criteria.and(criteriaSub);
    }

    private List<OrderEsDTO> copyList(List<OrderEs> list) {
        if (list == null || list.isEmpty()) {
            return Collections.emptyList();
        }
        List<OrderEsDTO> targetList = new ArrayList<OrderEsDTO>(list.size());
        for (OrderEs orderEs : list) {
            OrderEsDTO orderEsDTO = EntityUtil.copy(orderEs, OrderEsDTO.class);
            setOrder(orderEsDTO, orderEs);
            targetList.add(orderEsDTO);
        }
        return targetList;
    }

    private void setOrder(OrderEsDTO orderEsDTO, OrderEs orderEs) {
        try {
            Integer type = orderEs.getType();
            if (SystemBusinessType.OUTBOUND_TRAVEL.getCode() == type) {
                orderEsDTO.setTripOrder(EntityUtil.copy(orderEs.getTripOrder(), TripOrderEsDTO.class));
            } else if (SystemBusinessType.FIXED_PACKAGE_TICKET.getCode() == type) {
                orderEsDTO.setSeasonOrder(EntityUtil.copy(orderEs.getSeasonOrder(), SeasonOrderEsDTO.class));
            } else if (SystemBusinessType.HOTEL.getCode() == type) {
                orderEsDTO.setHotelOrder(EntityUtil.copy(orderEs.getHotelOrder(), HotelOrderEsDTO.class));
            } else if (SystemBusinessType.AIR_TICKET.getCode() == type) {
                AirOrderEs airOrderEs = orderEs.getAirOrder();
                List<AirOrderTripEs> airOrderTripList = airOrderEs.getAirOrderTripList();
                AirOrderEsDTO airOrderEsDTO = EntityUtil.copy(airOrderEs, AirOrderEsDTO.class);
                airOrderEsDTO.setAirOrderTripList(EntityUtil.copyList(airOrderTripList, AirOrderTripEsDTO.class));
                orderEsDTO.setAirOrder(airOrderEsDTO);
            } else if (SystemBusinessType.TRAIN_TICKET.getCode() == type) {
                orderEsDTO.setTrainOrder(EntityUtil.copy(orderEs.getTrainOrder(), TrainOrderEsDTO.class));
            } else if (SystemBusinessType.SHIP_TICKET.getCode() == type) {
                ShipOrderEs shipOrderEs = orderEs.getShipOrder();
                List<ShipOrderTripEs> shipOrderTripList = shipOrderEs.getShipOrderTripList();
                ShipOrderEsDTO shipOrderEsDTO = EntityUtil.copy(shipOrderEs, ShipOrderEsDTO.class);
                shipOrderEsDTO.setShipOrderTripList(EntityUtil.copyList(shipOrderTripList, ShipOrderTripEsDTO.class));
                orderEsDTO.setShipOrder(shipOrderEsDTO);
            } else if (SystemBusinessType.BUS_TICKET.getCode() == type) {
                orderEsDTO.setBusOrder(EntityUtil.copy(orderEs.getBusOrder(), BusOrderEsDTO.class));
            } else if (SystemBusinessType.AIR_EXPRESS.getCode() == type) {
                orderEsDTO.setAirportExpressOrder(EntityUtil.copy(orderEs.getAirportExpressOrder(), AirportExpressOrderEsDTO.class));
            } else if (SystemBusinessType.ATTRACTION_TICKET.getCode() == type) {
                orderEsDTO.setScenicOrder(EntityUtil.copy(orderEs.getScenicOrder(), ScenicOrderEsDTO.class));
            } else if (SystemBusinessType.LOCAL_FUN.getCode() == type) {
                orderEsDTO.setLocalFunOrder(EntityUtil.copy(orderEs.getLocalFunOrder(), LocalFunOrderEsDTO.class));
            } else if (SystemBusinessType.COMMODITY.getCode() == type) {
               List<CommodityOrderDetailEs> commodityOrderDetailList = orderEs.getCommodityOrder().getCommodityOrderDetailList();
                CommodityOrderEsDTO commodityOrderEsDTO = new CommodityOrderEsDTO();
                commodityOrderEsDTO.setCommodityOrderDetailList(EntityUtil.copyList(commodityOrderDetailList, CommodityOrderDetailEsDTO.class));
                orderEsDTO.setCommodityOrder(commodityOrderEsDTO);
            }
        } catch (Exception e) {
            log.error("ES转换DTO异常：id = ", orderEs.getId());
        }
    }

    /**
     * 计算前端展示的订单状态
     *
     * @param orderEs
     */
    private void setFrontOrderStatusAndFilterOrderStatus(OrderEs orderEs) {
        int type = orderEs.getType();
        int paymentStatus = orderEs.getPaymentStatus() == null?0:orderEs.getPaymentStatus();
        int scheduledStatus = orderEs.getScheduledStatus() == null?0:orderEs.getScheduledStatus();
        int orderStatus = orderEs.getOrderStatus() == null?0:orderEs.getOrderStatus();
        int cancelStatus = orderEs.getCancelStatus() == null?0:orderEs.getCancelStatus();
        if (SystemBusinessType.OUTBOUND_TRAVEL.getCode() == type || SystemBusinessType.INBOUND_TRAVEL.getCode() == type) {
            // 旅行团
            if (paymentStatus == 0) {
                orderEs.setFrontOrderStatus(AppOrderStatus.UN_PAYMENT.getCode());
                orderEs.setFilterOrderStatus(AppFilterOrderStatus.UN_PAYMENT.getCode());
            } else if (paymentStatus == 1 && cancelStatus != 0) {
                orderEs.setFrontOrderStatus(AppOrderStatus.PAYMENT.getCode());
                orderEs.setFilterOrderStatus(AppFilterOrderStatus.PAYMENT.getCode());
            } else if (cancelStatus == 2) {
                orderEs.setFrontOrderStatus(AppOrderStatus.UN_HANDLE.getCode());
                orderEs.setFilterOrderStatus(AppFilterOrderStatus.AFTER_SALE.getCode());
            } else if (cancelStatus == 3) {
                orderEs.setFrontOrderStatus(AppOrderStatus.UN_REFUND.getCode());
                orderEs.setFilterOrderStatus(AppFilterOrderStatus.AFTER_SALE.getCode());
            } else if (cancelStatus == 5) {
                orderEs.setFrontOrderStatus(AppOrderStatus.REFUND_SUCCESS.getCode());
                orderEs.setFilterOrderStatus(AppFilterOrderStatus.AFTER_SALE.getCode());
            }
        } else if (SystemBusinessType.AIR_EXPRESS.getCode() == type) {
            // 机场快线
            if (paymentStatus == OrderPaymentStatus.UN_PAYMENT.getCode() && scheduledStatus == 0 && cancelStatus == 0) {
                orderEs.setFrontOrderStatus(AppOrderStatus.UN_PAYMENT.getCode());
                orderEs.setFilterOrderStatus(AppFilterOrderStatus.UN_PAYMENT.getCode());
            } else if (paymentStatus == OrderPaymentStatus.UN_PAYMENT.getCode() && scheduledStatus == OrderScheduledStatus.RESERVE_SUCCESS.getCode() && cancelStatus == 0) {
                orderEs.setFrontOrderStatus(AppOrderStatus.PAYMENT.getCode());
                orderEs.setFilterOrderStatus(AppFilterOrderStatus.PAYMENT.getCode());
            } else if (paymentStatus == OrderPaymentStatus.ALREADY_PAYMENT.getCode() && scheduledStatus == OrderScheduledStatus.RESERVE_FAIL.getCode() && cancelStatus == 0) {
                orderEs.setFrontOrderStatus(AppOrderStatus.RESERVE_FAIL.getCode());
                orderEs.setFilterOrderStatus(AppFilterOrderStatus.CANCEL.getCode());
            } else if (paymentStatus == OrderPaymentStatus.ALREADY_CANCEL.getCode() && scheduledStatus == 0 && cancelStatus == 0) {
                orderEs.setFrontOrderStatus(AppOrderStatus.TIME_OUT_CANCEL.getCode());
                orderEs.setFilterOrderStatus(AppFilterOrderStatus.CANCEL.getCode());
            } else if (paymentStatus == OrderPaymentStatus.ALREADY_PAYMENT.getCode()
                    && (scheduledStatus == OrderScheduledStatus.CONFIRM_RESERVE.getCode()
            || scheduledStatus == OrderScheduledStatus.RESERVE_SUCCESS.getCode()
            || scheduledStatus == OrderScheduledStatus.RESERVE_FAIL.getCode())
                    && (cancelStatus == OrderCancelStatus.UNDER_APPROVAL.getCode()
                    || cancelStatus == OrderCancelStatus.APPROVAL_FAIL.getCode())) {
                orderEs.setFrontOrderStatus(AppOrderStatus.UN_HANDLE.getCode());
                orderEs.setFilterOrderStatus(AppFilterOrderStatus.AFTER_SALE.getCode());
            } else if(paymentStatus == OrderPaymentStatus.ALREADY_PAYMENT.getCode() &&
            scheduledStatus == OrderScheduledStatus.RESERVE_SUCCESS.getCode()
            && cancelStatus == 0) {
                orderEs.setFrontOrderStatus(AppOrderStatus.PAYMENT.getCode());
                orderEs.setFrontOrderStatus(AppFilterOrderStatus.PAYMENT.getCode());
            } else if (paymentStatus == OrderPaymentStatus.ALREADY_PAYMENT.getCode() && (scheduledStatus == OrderScheduledStatus.CONFIRM_RESERVE.getCode()
                    || scheduledStatus == OrderScheduledStatus.RESERVE_SUCCESS.getCode()
                    || scheduledStatus == OrderScheduledStatus.RESERVE_FAIL.getCode())
                    && (cancelStatus == OrderCancelStatus.APPROVAL_SUCCESS.getCode())) {
                orderEs.setFrontOrderStatus(AppOrderStatus.UN_REFUND.getCode());
                orderEs.setFilterOrderStatus(AppFilterOrderStatus.AFTER_SALE.getCode());
            } else if (paymentStatus == OrderPaymentStatus.ALREADY_PAYMENT.getCode() && (scheduledStatus == OrderScheduledStatus.CONFIRM_RESERVE.getCode()
                    || scheduledStatus == OrderScheduledStatus.RESERVE_SUCCESS.getCode()
                    || scheduledStatus == OrderScheduledStatus.RESERVE_FAIL.getCode())
                    && (cancelStatus == OrderCancelStatus.ALREADY_REFUND.getCode())) {
                orderEs.setFrontOrderStatus(AppOrderStatus.REFUND_SUCCESS.getCode());
                orderEs.setFilterOrderStatus(AppFilterOrderStatus.AFTER_SALE.getCode());
            }
        } else if (SystemBusinessType.COMMODITY.getCode() == type) {
            // 商品
            if (orderStatus == 1 && paymentStatus == 1 && scheduledStatus == 0 && cancelStatus == 0) {
                orderEs.setFrontOrderStatus(AppOrderStatus.UN_PAYMENT.getCode());
                orderEs.setFilterOrderStatus(AppFilterOrderStatus.UN_PAYMENT.getCode());
            } else if (paymentStatus == 2 && scheduledStatus == 3 && cancelStatus == 0) {
                orderEs.setFrontOrderStatus(AppOrderStatus.UN_CONFIRM.getCode());
                orderEs.setFilterOrderStatus(AppFilterOrderStatus.PAYMENT.getCode());
            } else if (orderStatus == 2 && paymentStatus == 2 && scheduledStatus == 1 && cancelStatus == 0) {
                orderEs.setFrontOrderStatus(AppOrderStatus.UN_SHIP.getCode());
                orderEs.setFilterOrderStatus(AppFilterOrderStatus.PAYMENT.getCode());
            } else if (orderStatus == 7 && paymentStatus == 2 && scheduledStatus == 1 && cancelStatus == 0) {
                orderEs.setFrontOrderStatus(AppOrderStatus.SHIP.getCode());
                orderEs.setFilterOrderStatus(AppFilterOrderStatus.PAYMENT.getCode());
            }  else if (orderStatus == 3 && paymentStatus == 2 && scheduledStatus == 1 && cancelStatus == 0) {
                orderEs.setFrontOrderStatus(AppOrderStatus.UN_RECEIPT.getCode());
                orderEs.setFilterOrderStatus(AppFilterOrderStatus.PAYMENT.getCode());
            } else if (orderStatus == 6 && paymentStatus == 2 && scheduledStatus == 1 && cancelStatus == 0) {
                orderEs.setFrontOrderStatus(AppOrderStatus.UN_PICK_UP.getCode());
                orderEs.setFilterOrderStatus(AppFilterOrderStatus.PAYMENT.getCode());
            } else if (orderStatus == 5 && paymentStatus == 2 && scheduledStatus == 2 && cancelStatus == 0) {
                orderEs.setFrontOrderStatus(AppOrderStatus.RESERVE_FAIL.getCode());
                orderEs.setFilterOrderStatus(AppFilterOrderStatus.CANCEL.getCode());
            } else if (orderStatus == 8 && paymentStatus == 3 && scheduledStatus == 0 && cancelStatus == 0) {
                orderEs.setFrontOrderStatus(AppOrderStatus.TIME_OUT_CANCEL.getCode());
                orderEs.setFilterOrderStatus(AppFilterOrderStatus.CANCEL.getCode());
            } else if (orderStatus == 4 && paymentStatus == 2 && scheduledStatus == 1 && cancelStatus == 0) {
                orderEs.setFrontOrderStatus(AppOrderStatus.SUCCESS.getCode());
                orderEs.setFilterOrderStatus(AppFilterOrderStatus.COMPLETE.getCode());
            } else if (orderStatus == 9 && paymentStatus == 2 &&
                    (scheduledStatus == 1 || scheduledStatus == 2 || scheduledStatus == 3) &&
                    (cancelStatus == 1 || cancelStatus == 3)) {
                orderEs.setFrontOrderStatus(AppOrderStatus.UN_HANDLE.getCode());
                orderEs.setFilterOrderStatus(AppFilterOrderStatus.AFTER_SALE.getCode());
            } else if (orderStatus == 10 && paymentStatus == 2 &&
                    (scheduledStatus == 1 || scheduledStatus == 2 || scheduledStatus == 3) &&
                    cancelStatus == 2) {
                orderEs.setFrontOrderStatus(AppOrderStatus.UN_REFUND.getCode());
                orderEs.setFilterOrderStatus(AppFilterOrderStatus.AFTER_SALE.getCode());
            } else if (orderStatus == 11 && paymentStatus == 2 &&
                    (scheduledStatus == 1 || scheduledStatus == 2 || scheduledStatus == 3) &&
                    cancelStatus == 2)  {
                orderEs.setFrontOrderStatus(AppOrderStatus.REFUND_SUCCESS.getCode());
                orderEs.setFilterOrderStatus(AppFilterOrderStatus.AFTER_SALE.getCode());
            }
        } else {
            // 其他
            setFrontOrderStatusAndFilterOrderStatusCommon(orderEs);
        }
    }

    private void setFrontOrderStatusAndFilterOrderStatusCommon(OrderEs orderEs) {
        int paymentStatus = orderEs.getPaymentStatus() == null?0:orderEs.getPaymentStatus();
        int scheduledStatus = orderEs.getScheduledStatus() == null?0:orderEs.getScheduledStatus();
        int orderStatus = orderEs.getOrderStatus() == null?0:orderEs.getOrderStatus();
        int cancelStatus = orderEs.getCancelStatus() == null?0:orderEs.getCancelStatus();
        if (paymentStatus == OrderPaymentStatus.UN_PAYMENT.getCode() && scheduledStatus == 0 && cancelStatus == 0) {
            orderEs.setFrontOrderStatus(AppOrderStatus.UN_PAYMENT.getCode());
            orderEs.setFilterOrderStatus(AppFilterOrderStatus.UN_PAYMENT.getCode());
        } else if (paymentStatus == OrderPaymentStatus.ALREADY_PAYMENT.getCode()
                && scheduledStatus == OrderScheduledStatus.CONFIRM_RESERVE.getCode()
                && cancelStatus == 0) {
            orderEs.setFrontOrderStatus(AppOrderStatus.UN_CONFIRM.getCode());
            orderEs.setFilterOrderStatus(AppFilterOrderStatus.PAYMENT.getCode());
        } else if (paymentStatus == OrderPaymentStatus.ALREADY_PAYMENT.getCode()
                && scheduledStatus == OrderScheduledStatus.RESERVE_FAIL.getCode()
                && cancelStatus == 0) {
            orderEs.setFrontOrderStatus(AppOrderStatus.RESERVE_FAIL.getCode());
            orderEs.setFilterOrderStatus(AppFilterOrderStatus.CANCEL.getCode());
        } else if (paymentStatus == OrderPaymentStatus.ALREADY_CANCEL.getCode()
                && scheduledStatus == 0
                && cancelStatus == 0) {
            orderEs.setFrontOrderStatus(AppOrderStatus.TIME_OUT_CANCEL.getCode());
            orderEs.setFilterOrderStatus(AppFilterOrderStatus.CANCEL.getCode());
        } else if (paymentStatus == OrderPaymentStatus.ALREADY_PAYMENT.getCode()
                && scheduledStatus == OrderScheduledStatus.RESERVE_SUCCESS.getCode()
                && cancelStatus == 0) {
            orderEs.setFrontOrderStatus(AppOrderStatus.SUCCESS.getCode());
            orderEs.setFilterOrderStatus(AppFilterOrderStatus.COMPLETE.getCode());
        }  else if (paymentStatus == OrderPaymentStatus.ALREADY_PAYMENT.getCode()
                && (scheduledStatus == OrderScheduledStatus.CONFIRM_RESERVE.getCode()
                || scheduledStatus == OrderScheduledStatus.RESERVE_SUCCESS.getCode()
                || scheduledStatus == OrderScheduledStatus.RESERVE_FAIL.getCode())
                && (cancelStatus == OrderCancelStatus.UNDER_APPROVAL.getCode() || cancelStatus == OrderCancelStatus.APPROVAL_FAIL.getCode())) {
            orderEs.setFrontOrderStatus(AppOrderStatus.UN_HANDLE.getCode());
            orderEs.setFilterOrderStatus(AppFilterOrderStatus.AFTER_SALE.getCode());
        } else if (paymentStatus == OrderPaymentStatus.ALREADY_PAYMENT.getCode()
                && (scheduledStatus == OrderScheduledStatus.CONFIRM_RESERVE.getCode()
                || scheduledStatus == OrderScheduledStatus.RESERVE_SUCCESS.getCode()
                || scheduledStatus == OrderScheduledStatus.RESERVE_FAIL.getCode())
                && (cancelStatus == OrderCancelStatus.APPROVAL_SUCCESS.getCode())) {
            orderEs.setFrontOrderStatus(AppOrderStatus.UN_REFUND.getCode());
            orderEs.setFilterOrderStatus(AppFilterOrderStatus.AFTER_SALE.getCode());
        } else if (paymentStatus == OrderPaymentStatus.ALREADY_PAYMENT.getCode()
                && (scheduledStatus == OrderScheduledStatus.CONFIRM_RESERVE.getCode()
                || scheduledStatus == OrderScheduledStatus.RESERVE_SUCCESS.getCode()
                || scheduledStatus == OrderScheduledStatus.RESERVE_FAIL.getCode())
                && (cancelStatus == OrderCancelStatus.ALREADY_REFUND.getCode())) {
            orderEs.setFrontOrderStatus(AppOrderStatus.REFUND_SUCCESS.getCode());
            orderEs.setFilterOrderStatus(AppFilterOrderStatus.AFTER_SALE.getCode());
        }
    }

    @Override
    public void updateStatusToEs(Long id, Integer type, Integer orderStatus, Integer paymentStatus, Integer scheduledStatus, Integer cancelStatus, String queryNumber) {
        CompletableFuture.runAsync(() -> {
            try {
                OrderEs orderEs = new OrderEs();
                orderEs.setId(id);
                orderEs.setType(type);
                orderEs.setOrderStatus(orderStatus);
                orderEs.setPaymentStatus(paymentStatus);
                orderEs.setScheduledStatus(scheduledStatus);
                orderEs.setCancelStatus(cancelStatus);
                if(Objects.nonNull(queryNumber)) {
                    orderEs.setQueryNumber(queryNumber);
                }
                setFrontOrderStatusAndFilterOrderStatus(orderEs);
                Document document = Document.parse(JSONUtil.toJsonStr(orderEs));
                elasticsearchRestTemplate.update(UpdateQuery.builder(id.toString())
                        .withDocAsUpsert(true)
                        .withDocument(document).build(), IndexCoordinates.of(ElasticSearchConstant.ORDER_INDEX));
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    @Override
    public void updateStatusToEs(Long id, Integer type, Integer orderStatus, Integer paymentStatus, Integer scheduledStatus, Integer cancelStatus) {
        updateStatusToEs(id,type,orderStatus,paymentStatus,scheduledStatus,cancelStatus,null);
    }

    @Override
    public Result<MobileQueryDTO> queryByReq(MobileQueryReq req) throws Exception {
        MobileQueryDTO dto = new MobileQueryDTO();
        // 判断查询编号是否是询价单,询价单调用
        if(req.getOrderNumber().startsWith(NumberHeadCode.INQUIRY.getCode())) {
            Long id = customizedTripScheduleInformationService.query(req.getOrderNumber(), req.getQueryNumber());
            if(id == null) {
                return Result.failed(new BusinessException(SystemError.SYS_433, "查无此单"));
            }
            dto.setId(id);
            dto.setType(SystemBusinessType.OUTBOUND_CUSTOMIZATION.getCode());
        } else {
            OrderEs orderEsByOrderNumber = orderEsMapper.findOrderEsByOrderNumberAndQueryNumber(req.getOrderNumber(), req.getQueryNumber());
            if (orderEsByOrderNumber == null) {
                return Result.failed(new BusinessException(SystemError.SYS_433, "查无此单"));
            }
            dto = EntityUtil.copy(orderEsByOrderNumber, MobileQueryDTO.class);
        }

        return Result.success(dto);
    }

    @Override
    public Result delete(Long id,Long userId) {
        Optional<OrderEs> orderEsOptional = orderEsMapper.findByIdAndUserId(id,userId);
        if(orderEsOptional.isPresent()) {
            OrderEs orderEs = orderEsOptional.get();
            Integer frontOrderStatus = orderEs.getFrontOrderStatus();
            if(AppOrderStatus.TIME_OUT_CANCEL.getCode().equals(frontOrderStatus)) {
                Document document = Document.create();
                document.put("isDeleted",IsDeletedCode.YES.getCode());
                try {
                    elasticsearchRestTemplate.update(UpdateQuery.builder(id.toString())
                            .withDocAsUpsert(true)
                            .withDocument(document).build(), IndexCoordinates.of(ElasticSearchConstant.ORDER_INDEX));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        return Result.success();
    }

    @Override
    public Result deleteAll() {
        orderEsMapper.deleteAll();
        return Result.success();
    }

    @Override
    public Result cancel(OrderCancelReq req) {
        Long orderId = req.getId();
        TokenUser tokenUser = req.getTokenUser();
        Long userId = tokenUser.getId();
        Optional<OrderEs> orderEsOptional = orderEsMapper.findByIdAndUserId(orderId,userId);
        if(orderEsOptional.isPresent()) {
            OrderEs orderEs = orderEsOptional.get();
            Integer type = orderEs.getType();
            Integer frontOrderStatus = orderEs.getFrontOrderStatus();
            Integer paymentStatus = orderEs.getPaymentStatus();
            Integer orderStatus = orderEs.getOrderStatus();
            if(AppOrderStatus.UN_PAYMENT.getCode().equals(frontOrderStatus)
            || AppOrderStatus.UN_CONFIRM.getCode().equals(frontOrderStatus)
            || AppOrderStatus.RESERVE_FAIL.getCode().equals(frontOrderStatus)
            || AppOrderStatus.SUCCESS.getCode().equals(frontOrderStatus)) {
                SystemBusinessType systemBusinessType = SystemBusinessType.parseCode(type);
                String id = orderId.toString();
                Long cancelReasonId = req.getCancelReasonId();
                String cancelReason = req.getCancelReason();
                String remark = req.getRemark();
                switch (systemBusinessType) {
                    case HOTEL:
                        HotelCancelOrderReq hotelCancelOrderReq = new HotelCancelOrderReq();
                        hotelCancelOrderReq.setOrderId(id);
                        hotelCancelOrderReq.setCancelReason(cancelReason);
                        hotelCancelOrderReq.setRemark(remark);
                        hotelOrderH5Service.cancel(hotelCancelOrderReq);
                        break;
                    case AIR_EXPRESS:
                        if(!AppOrderStatus.UN_PAYMENT.getCode().equals(frontOrderStatus)) {
                            AirportExpressOrderCancelReq airportExpressOrderCancelReq = new AirportExpressOrderCancelReq();
                            airportExpressOrderCancelReq.setRefundReason(cancelReason);
                            airportExpressOrderCancelReq.setRemark(remark);
                            return airportExpressOrderService.cancel(orderId,airportExpressOrderCancelReq,tokenUser);
                        } else {
                            return Result.failed(new BusinessException(SystemError.SYS_433, "待付款状态才能取消订单"));
                        }
                    case COMMODITY:
                        List<OrderCommodityRefundReq> orderCommodityRefundReqList = new ArrayList<>(1);
                        OrderCommodityRefundReq orderCommodityRefundReq = new OrderCommodityRefundReq();
                        orderCommodityRefundReq.setOrderId(orderId);
                        orderCommodityRefundReq.setPaymentStatus(paymentStatus);
                        orderCommodityRefundReq.setOrderStatus(orderStatus);
                        orderCommodityRefundReq.setRefundReason(cancelReason);
                        orderCommodityRefundReq.setRemark(remark);
                        orderCommodityRefundReqList.add(orderCommodityRefundReq);

                        orderService.cancelAppOrder(orderCommodityRefundReqList,tokenUser);
                        break;
                    case AIR_TICKET:
                        AirOrderCancelReq airOrderCancelReq = new AirOrderCancelReq();
                        airOrderCancelReq.setId(orderId);
                        airOrderCancelReq.setRefundReason(cancelReason);
                        airOrderCancelReq.setRemark(remark);
                        airProductOrderService.cancelOrder(airOrderCancelReq, tokenUser);
                        break;
                    case TRAIN_TICKET:
                        TrainCancelOrderAppReq trainCancelOrderAppReq = new TrainCancelOrderAppReq();
                        trainCancelOrderAppReq.setOrderId(orderId);
                        trainCancelOrderAppReq.setRefundReason(cancelReason);
                        trainCancelOrderAppReq.setRemark(req.getRemark());
                        trainOrderAppService.trainOrderCancel(trainCancelOrderAppReq);
                        break;
                    case BUS_TICKET:
                        busOrderAppService.busOrderCancel(orderId, tokenUser);
                        break;
                    case SHIP_TICKET:
//                callPayDTO = shipOrderService.getCallPayInfo(callPayReq.getId());
                        break;
                    case ATTRACTION_TICKET:
                        // TODO 景点门票取消订单未改变状态
                        scenicOrderAppService.cancelOrder(orderId);
                        break;
                    case LOCAL_FUN:
                        if(AppOrderStatus.UN_PAYMENT.getCode().equals(frontOrderStatus)) {
                            LocalFun0rderCancelReq localFun0rderCancelReq = new LocalFun0rderCancelReq();
                            localFun0rderCancelReq.setOrderId(id);
                            localFun0rderCancelReq.setCancelReason(cancelReason);
                            localFun0rderCancelReq.setRemark(remark);
                            localFunAppOrderService.cancelLocalFunOrder(localFun0rderCancelReq, orderEs.getCreateId());
                        } else if(AppOrderStatus.UN_CONFIRM.getCode().equals(frontOrderStatus)
                        || AppOrderStatus.RESERVE_FAIL.getCode().equals(frontOrderStatus)
                        || AppOrderStatus.SUCCESS.getCode().equals(frontOrderStatus)) {
                            AppLocalFunOrderRefundDetailReq localFunOrderRefundDetailReq = new AppLocalFunOrderRefundDetailReq();
                            localFunOrderRefundDetailReq.setOrderId(id);
                            localFunOrderRefundDetailReq.setCancelReason(cancelReason);
                            localFunOrderRefundDetailReq.setRemark(remark);

                            return localFunAppOrderService.cancelLocalFunOrderRefund(localFunOrderRefundDetailReq, orderEs.getCreateId());
                        }

                        break;
                    case OUTBOUND_TRAVEL:
                        //出境游
                        ClientOrderCancelReq clientOrderCancelReq = new ClientOrderCancelReq();
                        clientOrderCancelReq.setOrderId(orderId);
                        clientOrderCancelReq.setQuitReasonId(cancelReasonId);
                        clientOrderCancelReq.setQuitReason(cancelReason);
                        clientOrderCancelReq.setRemark(remark);
                        seriesOrderService.cancel2(clientOrderCancelReq);
                        break;
                    case INBOUND_TRAVEL:
                        //入境游
                        ClientOrderCancelReq clientOrderCancelReqInbound = new ClientOrderCancelReq();
                        clientOrderCancelReqInbound.setOrderId(orderId);
                        clientOrderCancelReqInbound.setQuitReasonId(cancelReasonId);
                        clientOrderCancelReqInbound.setQuitReason(cancelReason);
                        clientOrderCancelReqInbound.setRemark(remark);
                        seriesOrderService.cancel2(clientOrderCancelReqInbound);
                        break;
                    default:
                        Result.failed(SystemError.SYS_437);
                }
            }
        }
        return Result.success();
    }

}
